#include "stm32f4xx.h"
#include "OLED.h"
#include "OLED_Data.h"
#include "board.h"
#include "debug.h"

typedef struct
{
    double rx_temp;
    double rx_humi;
}rx_dht_data_t;

typedef struct 
{
    float rx_voltage;
    // float rx_current;
}rx_adc_data_t;

// 堆上创建结构体实例
typedef rx_dht_data_t* pxrx_dht_t;
typedef rx_adc_data_t* pxrx_adc_t;

// 确保结构体指针非野指针
rx_dht_data_t rx_dht_data;
pxrx_dht_t rx_dht_buffer = &rx_dht_data;
rx_adc_data_t rx_adc_data;
pxrx_adc_t rx_adc_buffer = &rx_adc_data;

extern SemaphoreHandle_t key_to_oled_ctr_wfi;

void oled_task(void* param)
{
    // 由于I2C为软件模拟通信时序，时序要求较为严格，进入临界区时关闭所有中断，确保OLED初始化完成
    taskENTER_CRITICAL();
    OLED_Init();
    taskEXIT_CRITICAL();

    rx_dht_buffer->rx_humi = 0;
    rx_dht_buffer->rx_temp = 0;
    rx_adc_buffer->rx_voltage = 0;

    uint32_t mq2_receive_notify_Value = 0;
    
    OLED_ShowString(72, 48, "mode: S", OLED_6X8); // 显示当前处于何种模式
    while (1)
    {   
        // 队列接收
        xQueueReceive(extern_to_oled_queue, &rx_dht_buffer->rx_humi, pdMS_TO_TICKS(100));
        xQueueReceive(extern_to_oled_queue, &rx_dht_buffer->rx_temp, pdMS_TO_TICKS(100));
        
        xQueueReceive(extern_to_oled_data, &rx_adc_buffer->rx_voltage, pdMS_TO_TICKS(100));
        // xQueueReceive(extern_to_oled_data, &rx_adc_buffer->rx_current, pdMS_TO_TICKS(100));

        // 等待ad任务转换完成发送通知
        xTaskNotifyWait(0, 0xFFFFFFFF, &mq2_receive_notify_Value, pdMS_TO_TICKS(100));
        
        OLED_ShowString(30, 0, "monitor data", OLED_6X8);

        if (xSemaphoreTake(key_to_oled_ctr_wfi, 0) == pdTRUE) // 如果有按键操作，显示当前低功耗状态
        {
            if(eTaskGetState(wfi_task_handle) == eSuspended)
            {
                OLED_ShowString(72, 48, "mode: N", OLED_6X8);
            }
            else
            {
                OLED_ShowString(72, 48, "mode: S", OLED_6X8);
            }
        }
        
        OLED_ShowString(0, 16, "temp:    C", OLED_6X8);
        OLED_ShowString(0, 24, "humi:   %RH", OLED_6X8);
        OLED_ShowSignedNum(30, 16, rx_dht_buffer->rx_temp, 3, OLED_6X8);
        OLED_ShowNum(30, 24, rx_dht_buffer->rx_humi, 3, OLED_6X8);

        /* mq4显示模块 */
        OLED_Printf(0, 32, OLED_6X8, "CH4conc:%d", (uint16_t)mq2_receive_notify_Value);

        /* 监测电压显示模块 */
        OLED_Printf(0, 40, OLED_6X8, "vol:%.2fV", rx_adc_buffer->rx_voltage);

        /* 照明控制模块 */
        OLED_ShowString(0, 48, "led:     ", OLED_6X8);
        GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_0) ? 
        OLED_ShowString(24, 48, "close", OLED_6X8) : OLED_ShowString(24, 48, "open", OLED_6X8);

        /*调用OLED_Update函数，将OLED显存数组的内容更新到OLED硬件进行显示*/
        OLED_Update();
    }
}
